#extension GL_ARB_texture_rectangle : enable

uniform sampler2DRect random;
uniform sampler2DRect blendrandom;

uniform float tileMotarWidth;
uniform float motarStep;
uniform float motarSmooth;
uniform float motarEdgeSmooth;

uniform vec4 motarColor;
uniform vec4 tileColor;

uniform sampler2DRect pattern0;
uniform vec2 patternDimension0;
uniform vec2 patternPosition0;

uniform sampler2DRect pattern1;
uniform vec2 patternDimension1;
uniform vec2 patternPosition1;

uniform float patternBlend;
uniform float patternBlendRange;
uniform bool patternReverse;
	
uniform float patternXOffset;
uniform float patternYOffset;
uniform float patternRandomOffset;


uniform float patternZoneScale0;
uniform float patternZoneScale1;
uniform bool patternZoneClamp0;
uniform bool patternZoneClamp1;

uniform float zoneBlend;
uniform float zoneBlendRange;
uniform bool zoneReverse;
	
uniform float zoneXOffset;
uniform float zoneYOffset;
uniform float zoneRandomOffset;

uniform sampler2D zones0;
uniform vec2 zone0Dimension;
uniform sampler2D zones1;
uniform vec2 zone1Dimension;

uniform float zoneMod;
uniform float zoneAdd;

uniform sampler2DRect colorMap0;
uniform sampler2DRect colorMap1;

uniform float colorBlend;
uniform float colorBlendRange;
uniform bool colorReverse;
	
uniform float colorXOffset;
uniform float colorYOffset;
uniform float colorRandomOffset;

uniform bool debug;

float blender(
	float xOffset, 
	float yOffset, 
	float randomOffset, 
	
	float blend, 
	float blendRange,
	bool reverse,
	
	vec2 coords,
	float random
){
	float maximumRadius = xOffset + yOffset + randomOffset;
	float blendRadius = (maximumRadius + blendRange);
	
	if(!reverse){
		blendRadius *= 1.0 - blend;
	} else {
		blendRadius *= blend;
	}
	
	float myX = 
		coords.x * xOffset + 
		coords.y * yOffset + 
		randomOffset * random;
		
	float myBlend = clamp((blendRadius - myX)  / (blendRange),0.0,1.0);
			
	if(!reverse) {
		myBlend = 1.0 - myBlend;
	}
	
	return myBlend;
}

uniform float patternScale;

void main(){

	vec2 gridCoords = floor(gl_TexCoord[0].xy / (tileMotarWidth * patternScale)) + vec2(0.5,0.5);
	vec2 gridPatternCoords = mod(gridCoords, patternDimension0);
	
	vec4 patternInfo = texture2DRect(pattern0, gridPatternCoords);
	vec4 patternInfo2 = texture2DRect(pattern0, gridPatternCoords+ vec2(patternDimension0.x * 2.0,0.0));
	vec4 patternIndices = texture2DRect(pattern0, gridPatternCoords + vec2(patternDimension0.x,0.0));
	
	vec2 patternCoords = floor(gridCoords / patternDimension0);
	vec2 tileCoords = patternIndices.xy + (patternCoords + vec2(patternIndices.z == 1.0,patternIndices.z == 2.0)) * patternDimension0 + vec2(0.5,0.5);
	
	vec3 randoms = texture2DRect(random, tileCoords).xyz;
	vec3 blendRandoms = texture2DRect(random, tileCoords + vec2(100.0,0.0)).xyz;
	
	float patternBlendValue = blender(
		patternXOffset,
		patternYOffset,
		patternRandomOffset,
		
		patternBlend,
		patternBlendRange,
		patternReverse,
		
		tileCoords,
		randoms.y
	);
	
	gridPatternCoords = mix(gridPatternCoords, mod(gridCoords, patternDimension1), patternBlendValue);
	
	patternInfo = mix(patternInfo, texture2DRect(pattern1, gridPatternCoords), patternBlendValue);
	patternIndices = mix(patternIndices, texture2DRect(pattern1, gridPatternCoords + vec2(patternDimension1.x,0.0)), patternBlendValue);
	
	patternCoords = mix(patternCoords, floor(gridCoords / patternDimension1), patternBlendValue);
	tileCoords = mix(tileCoords, patternIndices.xy + (patternCoords + vec2(patternIndices.z == 1.0,patternIndices.z == 2.0)) * patternDimension0 + vec2(0.5,0.5), patternBlendValue);
	
	randoms = texture2DRect(random, tileCoords).xyz;
	blendRandoms = texture2DRect(random, tileCoords + vec2(100.0,0.0)).xyz;
	
	//float h = max(1.0 - step(1.0 - motarStep,tt), (1.0 - patternInfo.r));
	//float h = step(MWF,tt) - step(1.0 - MWF,tt);
	vec2 zone0Coords = tileCoords;
	vec2 zone1Coords = tileCoords;
	if(patternZoneClamp0)zone0Coords = mod(tileCoords, patternDimension0);
	if(patternZoneClamp1)zone1Coords = mod(tileCoords, patternDimension0);
	
	vec4 zone0 = texture2D(zones0, zone0Coords / zone0Dimension * patternZoneScale0);
	vec4 zone1 = texture2D(zones1, zone1Coords / zone1Dimension * patternZoneScale1);
	
	float zoneBlendValue = blender(
		zoneXOffset,
		zoneYOffset,
		zoneRandomOffset,
		
		zoneBlend,
		zoneBlendRange,
		zoneReverse,
		
		tileCoords,
		randoms.y
	);
	
	int zone = int(mod(mod(floor(mix(zone0.x, zone1.x, zoneBlendValue) * 5.0), zoneMod) + zoneAdd, 5.0));
	//vec4 color = vec4(float(zone) / 5.0);
	
	vec4 color0 = texture2DRect(colorMap0, vec2(randoms.x * 100.0,zone));
	vec4 color1 = texture2DRect(colorMap1, vec2(randoms.x * 100.0,zone));
	
	float colorBlendValue = blender(
		colorXOffset,
		colorYOffset,
		colorRandomOffset,
		
		colorBlend,
		colorBlendRange,
		colorReverse,
		
		tileCoords,
		randoms.x
	);
		
	vec4 color = mix(color0, color1, colorBlendValue);
	
	///// MOTAR MODULATION ////////////////////////////////////////////////////////
		
	vec2 tileMask = gl_TexCoord[0].xy / (tileMotarWidth * patternScale);
	vec2 tileBrick = floor(tileMask);
	tileMask -= tileBrick;
	vec2 wh = max(1.0 - smoothstep(1.0 - motarStep, 1.0 - motarStep + motarSmooth, tileMask), (1.0 - patternInfo.gr));// - step(1.0 - MWF,ss);
	vec2 wh2 = max(smoothstep(motarStep - motarSmooth, motarStep, tileMask), (1.0 - patternInfo2.gr));// - step(1.0 - MWF,ss);
	
	vec2 wh3 = smoothstep(gl_TexCoord[1].xy, gl_TexCoord[1].xy + motarEdgeSmooth, gl_TexCoord[0].xy);
	vec2 wh4 = smoothstep(gl_TexCoord[1].zw, gl_TexCoord[1].zw - motarEdgeSmooth, gl_TexCoord[0].xy);
	
	float w = wh.x;
	float h = wh.y;
	float mColor = wh3.x * wh3.y * wh4.x * wh4.y;
	gl_FragColor = mix(motarColor, color, min(w, wh2.x) * min(h,wh2.y) * mColor);
	if(debug)gl_FragColor = vec4(float(zone)/4.0);
	//gl_FragColor =vec4(zone0Dimension,0.0,1.0);
	//if(debug)gl_FragColor = vec4(mColor,0.0,0.0, 1.0);//
	//texture2DRect(pattern0, gridCoords);//
	
}